package it.cst.entity.controller;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import it.cst.entity.Group;
import it.cst.entity.Match;
import it.cst.entity.Player;
import it.cst.entity.User;
import it.cst.entity.service.GroupService;
import it.cst.entity.service.MatchService;
import it.cst.entity.service.PlayerService;
import it.cst.entity.service.RoleService;
import it.cst.entity.service.UserService;
import it.cst.util.MatchSearchItem;
import it.cst.util.Paginator;
import it.cst.util.Roles;
import it.cst.util.SpringApplicationContext;
import it.cst.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;


@Controller
public class MatchController {
	private static final Logger logger = LoggerFactory.getLogger(MatchController.class);
	@Autowired
	private MatchService matchService;
	@Autowired
	private GroupService groupService;
	@Autowired
	private UserService userService;
	@Autowired
	private RoleService roleService;
	@Autowired
	private PlayerService playerService;
	
	
	public static int CURRENT_WINTHRESHOLD = 5;
	public static final String RED_COLOR = "red";
	public static final String BLU_COLOR = "blu";
	public static final String USER_RED_DEFENSE = "userRedDefense";
	public static final String USER_RED_ATTAC = "userRedAttac";
	public static final String USER_BLU_DEFENSE = "userBluDefense";
	public static final String USER_BLU_ATTAC = "userBluAttac";
	public static final String BLU_SCORE = "bluScore";
	public static final String RED_SCORE = "redScore";
	
	
	@RequestMapping("/addMatchData")
	public String addMatchData(Map<String, Object> map) {
		return "addMatchData";
	}
	
	
	@RequestMapping(value = "/insertMatchData", method = RequestMethod.POST)
	public String insertMatchData(@RequestParam(value=USER_RED_DEFENSE) String userRedDefense, @RequestParam(value=USER_RED_ATTAC) String userRedAttac, @RequestParam(value=RED_SCORE) String redScore, @RequestParam(value=USER_BLU_DEFENSE) String userBluDefense, @RequestParam(value=USER_BLU_ATTAC) String userBluAttac, @RequestParam(value=BLU_SCORE) String bluScore)
 {				
		Roles roles = Roles.getInstance(roleService);
		User urd = userService.getUser(userRedDefense);
		User ura = userService.getUser(userRedAttac);
		User ubd = userService.getUser(userBluDefense);
		User uba = userService.getUser(userBluAttac);
		Player urdP = new Player();
		Player uraP = new Player();
		Player ubdP = new Player();
		Player ubaP = new Player();
		Group redGrp = new Group();
		Group bluGrp = new Group();
		Match match = new Match();
		User currentUser = new Utils(userService).getCurrentUser();
		match.setAddedbyuser(currentUser.getId());
		match.setWinthreshold(CURRENT_WINTHRESHOLD);
		matchService.addMatch(match);
		logger.info("match added");
		redGrp.setIdmatch(match.getId());
		bluGrp.setIdmatch(match.getId());
		redGrp.setColor(RED_COLOR);
		bluGrp.setColor(BLU_COLOR);
		int rs = Integer.parseInt(redScore);
		int bs = Integer.parseInt(bluScore);
		redGrp.setScore(rs);
		bluGrp.setScore(bs);
		if(rs > bs){
			redGrp.setWinner(1);
			bluGrp.setWinner(0);
		}
		else{
			redGrp.setWinner(0);
			bluGrp.setWinner(1);
		}
		groupService.addGroup(redGrp);
		groupService.addGroup(bluGrp);
		logger.info("groups added");
		urdP.setIdgroup(redGrp.getId());
		urdP.setIduser(urd.getId());
		urdP.setIdrole(roles.getRole(Roles.DEFENSE_ROLE_NAME).getId());
		playerService.addPlayer(urdP);
		uraP.setIdgroup(redGrp.getId());
		uraP.setIduser(ura.getId());
		uraP.setIdrole(roles.getRole(Roles.ATTACK_ROLE_NAME).getId());
		playerService.addPlayer(uraP);
		ubdP.setIdgroup(bluGrp.getId());
		ubdP.setIduser(ubd.getId());
		ubdP.setIdrole(roles.getRole(Roles.DEFENSE_ROLE_NAME).getId());
		playerService.addPlayer(ubdP);
		ubaP.setIdgroup(bluGrp.getId());
		ubaP.setIduser(uba.getId());
		ubaP.setIdrole(roles.getRole(Roles.ATTACK_ROLE_NAME).getId());
		playerService.addPlayer(ubaP);
		logger.info("players added");
		List<User> userList = new ArrayList<User>();
		userList.add(urd);
		userList.add(ura);
		userList.add(ubd);
		userList.add(uba);
		Match newMatch = matchService.getMatch(match.getId());
		Utils.sendNotify(userList,currentUser,newMatch,"insertMatch");
		return "addMatchDataResult";
	}
	
	


	@RequestMapping("/matchGroupStat")
	public String matchGroupStat(Map<String, Object> map) {
		return "matchGroupStat";
	}
	
	
	@RequestMapping("/matchUserStat")
	public String matchUserStat(Map<String, Object> map) {
		return "matchUserStat";
	}

	
	
	@RequestMapping("/searchMatch")
	public ModelAndView searchMatch() {
		ModelAndView modelAndView = new ModelAndView("searchMatch");
		modelAndView.addObject("searchMatch", getSearchedMatch(null,null,null,null,null));
		return modelAndView;
	}
	
	
	
	@RequestMapping("/filterMatchs")
	public ModelAndView filterMatchs(@RequestParam(value="dateFilterMatchs") String dateFilterMatchs,@RequestParam(value="userFilterMatchs") String userFilterMatchs) {
		ModelAndView modelAndView = new ModelAndView("searchMatch");
		modelAndView.addObject("searchMatch", getSearchedMatch(null,null,null,dateFilterMatchs==""?null:dateFilterMatchs,userFilterMatchs==""?null:userFilterMatchs));
		return modelAndView;
	}
	
	
	@RequestMapping("/deleteMatchs")
	public ModelAndView deleteMatchs(@RequestParam(value="matchsToDelete") String matchsToDelete) {
		if(matchsToDelete != null){
			UserService us = (UserService) SpringApplicationContext.getBean("userService");
			matchsToDelete = matchsToDelete.substring(1);
			for(String ids : matchsToDelete.split(";")){
				Match m = matchService.getMatch(Integer.parseInt(ids));
				List<User> userList = new ArrayList<User>();
				for(Group g : m.getGroups()){
					for(Player p : g.getPlayers()){
						//userList.add(p.getUser());
						userList.add(us.getUser(p.getIduser()));
						playerService.removePlayer(p);
					}
					groupService.removeGroup(g);
				}
				Utils.sendNotify(userList,new Utils(userService).getCurrentUser(),m,"deleteMatch");
				matchService.removeMatch(m);				
			}
		}
		ModelAndView modelAndView = new ModelAndView("searchMatch");
		modelAndView.addObject("searchMatch", getSearchedMatch(null,null,null,null,null));
		return modelAndView;
	}
	
	
	

	
	
	
	
	@RequestMapping("/navSearchMatch")
	public ModelAndView searchMatch(@RequestParam(value="idMatch") String idMatch, @RequestParam(value="operator") String operator,@RequestParam(value="order") String order,@RequestParam(value="dateFilterMatchs") String dateFilterMatchs,@RequestParam(value="userFilterMatchs") String userFilterMatchs) {
		ModelAndView modelAndView = new ModelAndView("searchMatch");
		modelAndView.addObject("searchMatch", getSearchedMatch(idMatch,operator,order,dateFilterMatchs==""?null:dateFilterMatchs,userFilterMatchs==""?null:userFilterMatchs));
		return modelAndView;
	}
	
	
	
	@SuppressWarnings("unchecked")
	private Paginator getSearchedMatch(String idMatch,String operator,String order,String date,String user){
		String pattern = "yyyy-MM-dd hh:mm:ss";
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Roles roles = Roles.getInstance(roleService);
		final int numPageItems = 2;
		if(order == null){
			order = "DESC";
		}
		Integer idM = null;
		if(idMatch != null){
			idM = Integer.parseInt(idMatch);
		}
		Paginator pg = matchService.listMatch(numPageItems,idM,operator,order,date,user);
		//refill paginator with list of MatchSearchItem
		List<Match> lm =(List<Match>) pg.getObjList();
		List<MatchSearchItem> msl = new ArrayList<MatchSearchItem>();
		for(Match m : lm){
			MatchSearchItem msi = new MatchSearchItem();
			msi.setDateTime(sdf.format(m.getTimestamp()));
			msi.setMatchId(m.getId());
			List<Group> gl = groupService.listGroup(m.getId());
			   if(gl != null && !gl.isEmpty()){
				   for(Group g : gl){
					   List<Player> pl = playerService.listGroupPlayer(g.getId());
					   if(pl != null && !pl.isEmpty()){
						   for(Player p : pl){
							   User u = userService.getUser(p.getIduser());
							   if(g.getColor().equalsIgnoreCase(MatchController.RED_COLOR)){
								   msi.setRedScore(g.getScore());
								   if(p.getIdrole().compareTo(roles.getRole(Roles.DEFENSE_ROLE_NAME).getId()) == 0)
								   {
									   msi.setUserRedDefense(u);
								   }
								   else
								   {
									   msi.setUserRedAttack(u);
								   }
							   }
							   else{
								   msi.setBluScore(g.getScore());
								   if(p.getIdrole().compareTo(roles.getRole(Roles.DEFENSE_ROLE_NAME).getId()) == 0)
								   {
									   msi.setUserBluDefense(u);
								   }
								   else
								   {
									   msi.setUserBluAttack(u);
								   }
							   }
						   } 
					   }
				   }
			   }
			msl.add(msi);   
		}
		pg.setObjList(msl);
		return pg;
	}
}
